package com.zyj.jetpackdemo.composes

import android.content.Context
import android.preference.PreferenceActivity
import android.util.Log
import android.widget.Toast
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.*
import androidx.compose.foundation.shape.AbsoluteCutCornerShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import com.zyj.jetpackdemo.stickyContentData
import com.zyj.jetpackdemo.stickyGrouped
import com.zyj.jetpackdemo.testItems
import com.zyj.jetpackdemo.ui.theme.MajorBlueColor
import com.zyj.jetpackdemo.ui.theme.Teal200
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch

/**
 * Basic Lists
 * include Column an Row
 */
@Composable
fun BasicListCompose() {
    Column(modifier = Modifier.fillMaxWidth()) {
        BasicColumn()
        Text(
            text = "-----------------------Divider-----------------------",
            modifier = Modifier
                .fillMaxWidth()
                .height(30.dp)
                .wrapContentSize(align = Alignment.Center)
        )
        BasicRow()
    }
}

/**
 * Column
 */
@Composable
fun BasicColumn() {
    val scrollState = rememberScrollState()
    Column(
        modifier = Modifier
            .fillMaxHeight(0.5f)
            .verticalScroll(scrollState)
    ) {
        testItems.forEach {
            Text(
                text = "vertical $it", modifier = Modifier
                    .background(color = Teal200)
                    .height(50.dp)
                    .padding(vertical = 8.dp)
                    .wrapContentSize(align = Alignment.Center)
            )
            Spacer(modifier = Modifier.height(16.dp))
        }
    }
}

/**
 * Row
 */
@Composable
fun BasicRow() {
    val scrollState = rememberScrollState()
    Row(
        modifier = Modifier
            .fillMaxHeight(0.5f)
            .horizontalScroll(scrollState)
    ) {
        testItems.forEach {
            Text(
                text = "horizontal_$it", modifier = Modifier
                    .background(color = Teal200)
                    .height(30.dp)
                    .padding(horizontal = 8.dp)
                    .wrapContentSize(align = Alignment.Center)
            )
            Spacer(modifier = Modifier.width(16.dp))
        }
    }
}

/**
 * Lazy Composables
 * 与Column 和 Row的区别就是 Lazy系列的加载机制类似于RecyclerView, 只加载可见区域
 * 使用的是官方文档的LazyListScope DSL的示例代码
 */
@Composable
fun LazyListCompose() {
    Column {
        LazyListColumn()
        Text(
            text = "-----------------------Divider-----------------------",
            modifier = Modifier
                .fillMaxWidth()
                .height(30.dp)
                .wrapContentSize(align = Alignment.Center)
        )
        LazyListRow()
    }
}

/**
 * LazyColumn
 */
@Composable
fun LazyListColumn() {
    LazyColumn() {
        // Add a single item
        item {
            Text(text = "First item")
        }

        // Add 5 items
        // 此处是需要显示的item个数
        items(5) { index ->
            Text(text = "Item: $index")
        }

        // Add another single item
        item {
            Text(text = "Last item")
        }
    }
}

/**
 * LazyRow
 */
@Composable
fun LazyListRow() {
    LazyRow() {
        // Add a single item
        item {
            Text(text = "First item")
        }

        // Add 5 items
        // 此处直接使用的数据集
        items(testItems) { index ->
            Text(text = "Item: $index")
        }

        // Add another single item
        item {
            Text(text = "Last item")
        }
    }
}

/**
 * Content Padding 组件内边距
 */
@Composable
fun ContentPadding() {
    LazyColumn(
        contentPadding = PaddingValues(horizontal = 16.dp, vertical = 8.dp),
        modifier = Modifier.background(color = MajorBlueColor)
    ) {
        item {
            Text(text = "padding 内边距")
        }
        items(testItems) {
            Text(text = it)
        }
    }
}


/**
 * Content Spacing
 * 组件和组件之间的间距
 *
 * 主要使用 verticalArrangement属性 和horizontalArrangement属性
 */
@Composable
fun ContentSpacing() {
    Column {

        ColumnSpacing()
        Text(
            text = "-----------------------Divider-----------------------",
            modifier = Modifier
                .fillMaxWidth()
                .height(30.dp)
                .wrapContentSize(align = Alignment.Center)
        )
        RowSpacing()
    }

}

/**
 * 纵向使用 verticalArrangement属性
 */
@Composable
fun ColumnSpacing() {
    Text(text = "verticalArrangement参数设置纵向外边距")

    LazyColumn(
        verticalArrangement = Arrangement.spacedBy(4.dp),
    ) {
        items(testItems) {
            Text(text = it, modifier = Modifier.background(color = MajorBlueColor))
        }
    }

}


/**
 * 横向使用 horizontalArrangement属性
 */
@Composable
fun RowSpacing() {
    Text(text = "horizontalArrangement参数设置横向外边距")

    LazyRow(
        horizontalArrangement = Arrangement.spacedBy(4.dp),
    ) {
        items(testItems) {
            Text(text = it, modifier = Modifier.background(color = MajorBlueColor))
        }
    }
}

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun StickyHeader() {
    LazyColumn(modifier = Modifier.fillMaxWidth()) {
        stickyHeader {
            Text(
                text = "Sticky Header", modifier = Modifier
                    .fillMaxWidth()
                    .background(color = MajorBlueColor)
            )
        }

        items(stickyContentData[0]) { item ->
            Text(text = item)
        }
    }
}

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun StickyGroupHeader() {
    LazyColumn(modifier = Modifier.fillMaxWidth()) {
        stickyGrouped.forEach { (initial, content) ->
            stickyHeader {
                Text(
                    text = initial, modifier = Modifier
                        .fillMaxWidth()
                        .background(color = MajorBlueColor)
                )
            }

            items(content) { item ->
                Text(text = item)
            }
        }

    }
}

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun GridCompose(content: List<String>) {
    LazyVerticalGrid(
        cells = GridCells.Fixed(3),
    ) {
        items(content) {
            Text(text = it, Modifier.background(color = (MajorBlueColor)))
        }
    }
}

/**
 * Reacting to scroll position
 * 根据滑动事件做相应效果, 类似于view的滑动监听
 */
@OptIn(ExperimentalAnimationApi::class) // AnimatedVisibility
@Composable
fun ReactingScroll(context:Context){
    // Remember our own LazyListState
    val listState = rememberLazyListState()
    Box {
        LazyColumn(state = listState, modifier = Modifier.fillMaxWidth()) {
            items(stickyContentData[0]) {
                Text(text = it)
            }
        }

        // Show the button if the first visible item is past
        // the first item. We use a remembered derived state to
        // minimize unnecessary compositions
        val showButton by remember {
            derivedStateOf {
                listState.firstVisibleItemIndex > 0
            }
        }

        AnimatedVisibility(visible = showButton) {
            Button(content = {Text("click")}, modifier = Modifier.background(MajorBlueColor), onClick = {
                Toast.makeText(context, "Click", Toast.LENGTH_SHORT).show()
            })
        }
    }
}

@Composable
fun ControllingScroll(){
    val listState = rememberLazyListState()
    // Remember a CoroutineScope to be able to launch
    val coroutineScope = rememberCoroutineScope()

    LazyColumn(state = listState, modifier = Modifier.fillMaxWidth()) {
        items(stickyContentData[0]) {
            Text(text = it)
        }
    }

    Button(
        content= {Text("click")},
        onClick = {
            // 点击后 会滚动回下标为0的位置
            coroutineScope.launch {
                // Animate scroll to the first item
                listState.animateScrollToItem(index = 0)
            }
        }
    )
}

@Composable
fun LargeDataOfPaging(){
    Text("与paging使用需要paging版本>3.0, 一直添加依赖失败, 暂时搁置")
}
